﻿using System;
using Cpu6502.Opcodes;

namespace Cpu6502
{
    public class OpcodeMapper
    {
        public Opcode[] Map = new Opcode[]
        {
            // 0x00-0x0F
            new BRK(),                  // BRK B
            new ORA_Index_Indirect(),   // ORA (d,x)
            new NOP(),                  // cop b
            new NOP(),                  // ora d,S
            new NOP(),                  // Tsb d
            new NOP(),                  // Ora d
            new ASL_ZP(),               // ASL d
            new NOP(),                  // ora [d]
            new PHP(),                  // PHP
            new ORA_I(),                // ORA #
            new ASL(),                  // ASL A
            new NOP(),                  // phd
            new NOP(),                  // Tsb a
            new ORA_A(),                // ORA a
            new ASL_A(),                // ASL a
            new NOP(),                  // ora al
            
            // 1x00 - 1x0F
            new BPL(),                  // BPL r
            new ORA_Indirect_Index(),   // ORA (d),Y
            new NOP(),                  // Ora (d)
            new NOP(),                  // Ora (d,s), Y
            new NOP(),                  // TRB D
            new ORA_ZP_X(),             // ORA D,X
            new ASL_ZP_X(),             // ASL D,X
            new NOP(),                  // ORA [d], Y
            new CLC(),                  // CLC
            new ORA_A_Y(),              // ORA a,Y
            new INC_A(),                // Inc A
            new NOP(),                  // tcs
            new NOP(),                  // Trb a
            new ORA_A_X(),              // ORA a,X
            new ASL_A_X(),              // ASL a,X
            new NOP(),                  // ORA al, X

            //2x00 - 2x0F
            new JSR_A(),                // JSR a
            new AND_Index_Indirect(),   // AND (d,X)
            new NOP(),                  // JSL AL
            new NOP(),                  // AND D,S
            new BIT_ZP(),               // BIT D
            new AND_ZP(),               // AND D
            new ROL_ZP(),               // ROL D
            new NOP(),                  // AND [D]
            new PLP(),                  // PLP
            new AND_I(),                // AND #
            new ROL(),                  // ROL A
            new NOP(),                  // PLD
            new BIT_A(),                // BIT A
            new AND_A(),                // AND a
            new ROL_A(),                // ROL a
            new NOP(),                  // AND AL

            //3x00 - 3x0F
            new BMI(),                  // BMI R
            new AND_Indirect_Index(),   // AND (D),Y
            new AND_ZP(),               // AND D
            new NOP(),                  // AND (D,S,),Y
            new NOP(),                  // BIT D,X
            new AND_ZP_X(),             // AND D,X
            new ROL_ZP_X(),             // ROL D,X
            new NOP(),                  // AND [D],Y
            new SEC(),                  // SEC
            new AND_A_Y(),              // AND A,Y
            new DEC_A(),                // DEC A
            new NOP(),                  // TSC
            new NOP(),                  // BIT A,X
            new AND_A_X(),              // AND A,X
            new ROL_A_X(),              // ROL A,X
            new NOP(),                  // AND AL,X

            //4x00 - 4x0F
            new RTI(),                  // RTI
            new EOR_Index_Indirect(),   // EOR (D,X)
            new NOP(),                  // WDM
            new NOP(),                  // EOR D,S
            new NOP(),                  // MVP S,D
            new EOR_ZP(),               // EOR D
            new LSR_ZP(),               // LSR D
            new NOP(),                  // EOR [D]
            new PHA(),                  // PHA
            new EOR_I(),                // EOR #
            new LSR(),                  // LSR A
            new NOP(),                  // PHK
            new JMP_A(),                // JMP A
            new EOR_A(),                // EOR A
            new LSR_A(),                // LSR A
            new NOP(),                  // EOR AL

            //5x00 - 5x0F
            new BVC(),                  // BVC R
            new EOR_Index_Indirect(),   // EOR (D),Y
            new NOP(),                  // EOR (D)
            new NOP(),                  // EOR (D,S),Y
            new NOP(),                  // MVN S,D
            new EOR_ZP_X(),             // EOR D,X
            new LSR_ZP_X(),             // LSR D,X
            new NOP(),                  // EOR [D],Y
            new CLI(),                  // CLI
            new EOR_A_Y(),              // EOR A,Y
            new NOP(),                  // PHY
            new NOP(),                  // TCD
            new NOP(),                  // JMP AL
            new EOR_A_X(),              // EOR A,X
            new LSR_A_X(),              // LSR A,X
            new NOP(),                  // EOR AL,X

            //6x00 - 6x0F
            new RTS(),                  // RTS
            new ADC_Index_Indirect(),   // ADC (D,X)
            new NOP(),                  // PER RL
            new NOP(),                  // ADC D,S
            new NOP(),                  // STZ D
            new ADC_ZP(),               // ADC D
            new ROR_ZP(),               // ROR D
            new NOP(),                  // ADC [D]
            new PLA(),                  // PLA
            new ADC_I(),                // ADC #
            new ROR(),                  // ROR A
            new NOP(),                  // RTL
            new JMP_Indirect(),         // JMP (A)
            new ADC_A(),                // ADC A
            new ROR_A(),                // ROR A
            new NOP(),                  // ADC AL

            //7x00 - 7x0F
            new BVS(),                  // BVS R
            new ADC_Indirect_Index(),   // ADC (D),Y
            new NOP(),                  // ADC (D)
            new NOP(),                  // ADC (D,S),Y
            new NOP(),                  // STZ D,X
            new ADC_ZP_X(),             // ADC D,X
            new ROR_ZP_X(),             // ROR D,X
            new NOP(),                  // ADC [D],Y
            new SEI(),                  // SEI
            new ADC_A_Y(),              // ADC A,Y
            new NOP(),                  // PLY
            new NOP(),                  // TDC
            new NOP(),                  // JMP (A,X)
            new ADC_A_X(),              // ADC A,X
            new ROR_A_X(),              // ROR A,X
            new NOP(),                  // ADC AL,X

            //8x00 - 8x0F
            new NOP(),                  // BRA R
            new STA_Indexed_Indirect(), // STA (D,X)
            new NOP(),                  // BRL RL
            new NOP(),                  // STA D,S
            new STY_ZP(),               // STY D
            new STA_ZP(),               // STA D
            new STX_ZP(),               // STX D
            new NOP(),                  // STA [D]
            new DEY(),                  // DEY
            new NOP(),                  // BIT #
            new TXA(),                  // TXA
            new NOP(),                  // PHB 
            new STY_A(),                // STY A
            new STA_A(),                // STA A
            new STX_A(),                // STX A
            new NOP(),                  // STA AL

            //9x00 - 9x0F
            new BCC(),                  // BCC R
            new STA_Indirect_Indexed(), // STA (D),Y
            new NOP(),                  // STA (D)
            new NOP(),                  // STA (D,S),Y
            new STY_ZP_X(),             // STY D,X
            new STX_ZP_Y(),             // STX D,Y
            new NOP(),                  // STA [D],Y
            new TYA(),                  // TYA
            new STA_A_Y(),              // STA A,Y
            new TXS(),                  // TXS
            new NOP(),                  // TXY
            new NOP(),                  // STZ A
            new STA_A_X(),              // STA A,X
            new NOP(),                  // STZ A,X
            new NOP(),                  // STA AL,X

            //Ax00 - Ax0F
            new LDY_I(),                // LDY #
            new LDA_Indexed_Indirect(), // LDA (D,X)
            new LDX_I(),                // LDX #
            new NOP(),                  // LDA D,S
            new LDY_ZP(),               // LDY D
            new LDA_ZP(),               // LDA D
            new LDX_ZP(),               // LDX D
            new NOP(),                  // LDA [D]
            new TAY(),                  // TAY
            new LDA_I(),                // LDA #
            new TAX(),                  // TAX
            new NOP(),                  // PLB
            new LDY_A(),                // LDY A
            new LDA_A(),                // LDA A
            new LDX_A(),                // LDX A
            new NOP(),                  // LDA AL

            //Bx00 - Bx0F
            new BCS(),                  // BCS R
            new LDA_Indirect_Indexed(), // LDA (D),Y
            new LDA_ZP(),               // LDA (D)
            new NOP(),                  // LDA (D,S),Y
            new LDY_ZP_X(),             // LDY D,X
            new LDA_ZP_X(),             // LDA D,X
            new LDX_ZP_Y(),             // LDX D,Y
            new NOP(),                  // LDA [D],Y
            new CLV(),                  // CLV
            new LDA_A_Y(),              // LDA A,Y
            new TSX(),                  // TSX
            new NOP(),                  // TYX
            new LDY_A_X(),              // LDY A,X
            new LDA_A_X(),              // LDA A,X
            new LDX_A_Y(),              // LDX A,Y
            new NOP(),                  // LDA AL,X
            
            //Cx00 - Cx0F
            new CPY_I(),                // CPY #
            new CMP_Indexed_Indirect(), // CMP (D,X)
            new NOP(),                  // REP #
            new NOP(),                  // CMP D,S
            new CPY_ZP(),               // CPY D
            new CMP_ZP(),               // CMP D
            new DEC_ZP(),               // DEC D
            new NOP(),                  // CMP [D]
            new INY(),                  // INY
            new CMP_I(),                // CMP #
            new DEX(),                  // DEX
            new NOP(),                  // WAI
            new CPY_A(),                // CPY A
            new CMP_A(),                // CMP A
            new DEC_A(),                // DEC A
            new NOP(),                  // CMP AL

            //Dx00 - Dx0F
            new BNE(),                  // BNE R
            new CMP_Indirect_Indexed(), // CMP (D), Y
            new NOP(),                  // CMP (D)
            new NOP(),                  // CMP (D,S), Y
            new NOP(),                  // PEI D
            new CMP_ZP_X(),             // CMP D,X
            new DEC_ZP_X(),             // DEC D,X
            new NOP(),                  // CMP [D],Y
            new CLD(),                  // CLD
            new CMP_A_Y(),              // CMP A,Y
            new NOP(),                  // PHX
            new NOP(),                  // STP
            new NOP(),                  // JML (A)
            new CMP_A_X(),              // CMP A,X
            new DEC_A_X(),              // DEC A,X
            new NOP(),                  // CMP AL,X

            //Ex00 - Ex0F
            new CPX_I(),                // CPX #
            new SBC_Index_Indirect(),   // SBC (D,X)
            new NOP(),                  // SEP #
            new NOP(),                  // SBC D,S
            new CPX_ZP(),               // CPX D
            new SBC_ZP(),               // SBC D
            new INC_ZP(),               // INC D
            new NOP(),                  // SBC [D]
            new INX(),                  // INX
            new SBC_I(),                // SBC #
            new NOP(),                  // NOP
            new NOP(),                  // XBA
            new CPX_A(),                // CPX A
            new SBC_A(),                // SBC A
            new INC_A(),                // INC A
            new NOP(),                  // SBC AL

            //Fx00 - Fx0F
            new BEQ(),                  // BEQ R
            new SBC_Indirect_Index(),   // SBC (D), Y
            new NOP(),                  // SBC (D)
            new NOP(),                  // SBC (D,S),Y
            new NOP(),                  // PEA A
            new SBC_ZP_X(),             // SBC D,X
            new INC_ZP_X(),             // INC D,X
            new NOP(),                  // SBC [D],Y
            new SED(),                  // SED
            new SBC_A_Y(),              // SBC A,Y
            new NOP(),                  // PLX
            new NOP(),                  // XCE
            new NOP(),                  // JSR (A,X)
            new SBC_A_X(),              // SBC A,X
            new INC_A_X(),              // INC A,X
            new NOP(),                  // SBC AL,X

        };
    }
}
